package edu.fim.presentation.view;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;

import edu.fim.presentation.controller.ConsumerController;
import edu.fim.presentation.controller.FoodController;
import edu.fim.presentation.controller.exception.ControllerException;
import edu.fim.presentation.model.bean.Food;

public class MainForm extends AbstractForm {

	private static final long serialVersionUID = -659844447393947267L;

	private ConsumerController consumerController;
	// TODO private FoodController foodController;
	
	private JComboBox<Food> foodComboBox;
	private JLabel caloriesIndicator;

	public MainForm(
			String title,
			ConsumerController consumerController) {
		super(title);
		this.consumerController = consumerController;
		initialize();
		update();
	}

	public void setConsumerController(ConsumerController consumerController) {
		this.consumerController = consumerController;
	}

	public void update() {
		updateFoodComboBox();
		Double consumedCalories = consumerController.getCurrentConsumer().getConsumedCalories();
		caloriesIndicator.setText(consumedCalories.toString());
		pack();
	}
	
	private void updateFoodComboBox() {
		foodComboBox.removeAllItems();
		for (Food food : consumerController.getCurrentConsumer().getPreferences()) {
			foodComboBox.addItem(food);
		}
	}

	protected void initializeDynamicComponents() {
		initializeFoodComboBox();
		caloriesIndicator = new JLabel();
	}

	private void initializeFoodComboBox() {
		foodComboBox = new JComboBox<Food>();
		foodComboBox.setMinimumSize(new Dimension(150, 20));
		foodComboBox.setPreferredSize(new Dimension(150, 20));
		foodComboBox.setMaximumSize(new Dimension(150, 20));
		updateFoodComboBox();
	}

	protected void buildLayout() {
		getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
		
		getContentPane().add(createFoodManagementContainer());
		getContentPane().add(Box.createRigidArea(new Dimension(10, 10)));
		getContentPane().add(createInfoContainer());
		getContentPane().add(Box.createRigidArea(new Dimension(20, 20)));
		getContentPane().add(createButtonContainer());
	}
	
	private Container createFoodManagementContainer() {
		Container container = new Container();
		container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
		container.add(foodComboBox);
		container.add(criarComponenteRegistroConsumo());
		return container;
	}
	
	private Container createInfoContainer() {
		Container container = new Container();
		container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
		container.add(new JLabel("Total Calories Consumed: "));
		container.add(caloriesIndicator);
		container.add(createResetCaloriesButton());
		return container;
	}
	
	private Component createResetCaloriesButton() {
		AbstractButton button = new JButton("Reset Calories");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				resetCaloriesActionPerformed();
			}
		});
		return button;
	}

	private Container createButtonContainer() {
		Container container = new Container();
		container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
		container.add(createProfileAccessComponent());
		container.add(createRankComponent());
		container.add(createMenuConfigAccessComponent());
		container.add(createScheduleButton());
		container.add(createLogoutComponent());
		return container;
	}

	private Component createScheduleButton() {
		AbstractButton button = new JButton("Schedule");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				scheduleButtonActionPerformed();
			}
		});
		return button;
	}

	private Component criarComponenteRegistroConsumo() {
		AbstractButton componenteRegistroConsumo = new JButton("Register Ingestion");
		componenteRegistroConsumo.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				consumptionRegistrationComponentActionPerformed();
			}
		});
		return componenteRegistroConsumo;
	}
	
	private Component createProfileAccessComponent() {
		AbstractButton componenteAcessoPerfil = new JButton("Profile");
		componenteAcessoPerfil.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				profileAccessComponentActionPerformed(evt);
			}
		});
		return componenteAcessoPerfil;
	}
	
	private Component createRankComponent() {
		AbstractButton button = new JButton("Food Rank");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				rankComponentActionPerformed();
			}
		});
		return button;
	}
	
	private Component createMenuConfigAccessComponent() {
		AbstractButton button = new JButton("Menu Config");
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				menuConfigAccessComponentActionPerformed();
			}
		});
		return button;
	}
	
	private Component createLogoutComponent() {
		AbstractButton componenteEncerramento = new JButton("Logout");
		componenteEncerramento.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				logoutComponentActionPerformed();
			}
		});
		return componenteEncerramento;
	}

	private void consumptionRegistrationComponentActionPerformed() {
		Food food = (Food) foodComboBox.getSelectedItem();
		try {
			// TODO: Incrementar o atributo timesConsumed da classe Preferences
			consumerController.registerIngestion(food);
			update();
		}
		catch (ControllerException e) {
			e.printStackTrace();
			showMessage(e.getMessage());
		}
	}
	
	private void resetCaloriesActionPerformed() {
		try {
			consumerController.resetCalories();
		} catch (ControllerException e) {
			e.printStackTrace();
			showMessage("Calories could not be reset.");
		}
	}
	
	private void profileAccessComponentActionPerformed(ActionEvent evt) {
		Form telaPerfil = new ProfileForm("Perfil", consumerController);
		telaPerfil.setVisible(true);
	}
	
	private void rankComponentActionPerformed() {
		Form rankForm = new RankForm("Food Rank", consumerController);
		rankForm.setVisible(true);
	}
	
	private void menuConfigAccessComponentActionPerformed() {
		FoodController foodController = new FoodController();
		Form menuConfigForm = new MenuConfigForm("Menu Config", this, consumerController, foodController);
		menuConfigForm.setVisible(true);
	}
	
	private void scheduleButtonActionPerformed() {
		Form scheduleForm = new ScheduleForm("Schedule", consumerController);
		scheduleForm.setVisible(true);
	}
	
	private void logoutComponentActionPerformed() {
		setVisible(false);
	}
}